package com.dome.popup.myapplication.expandable;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.dome.popup.myapplication.CommonUtil;
import com.dome.popup.myapplication.ExpandableItem;
import com.dome.popup.myapplication.ExpandableSelectorListener;
import com.dome.popup.myapplication.OnExpandableItemClickListener;
import com.dome.popup.myapplication.R;
import com.dome.popup.myapplication.animation.ExpandableSelectorAnimator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by dgp on 2018/12/11
 * Description:
 */
public class ExpandablePopup extends FrameLayout {

    @SuppressLint("HandlerLeak")
    private Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            expand();
        }
    };
    private static final int DEFAULT_ANIMATION_DURATION = 300;
    private List<ExpandableItem> expandableItems = Collections.EMPTY_LIST;
    private List<View> buttons = new ArrayList<View>();
    private ExpandableSelectorAnimator expandableSelectorAnimator;
    private ExpandableSelectorListener listener;
    private OnExpandableItemClickListener clickListener;
    private boolean isFrist = true;
    private int animType = 0;//0:left 1:Right

    private boolean hideBackgroundIfCollapsed;
    private Drawable expandedBackground;

    public ExpandablePopup(@NonNull Context context) {
        this(context, null);
    }

    public ExpandablePopup(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ExpandablePopup(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initializeView(attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ExpandablePopup(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initializeView(attrs);
    }


    public void showExpandableItems(List<ExpandableItem> expandableItems) {
        validateExpandableItems(expandableItems);
        reset();
        setExpandableItems(expandableItems);
        renderExpandableItems();
        hookListeners();
        bringChildsToFront(expandableItems);
        ViewTreeObserver observer = this.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if(isFrist){
                    myHandler.sendEmptyMessageDelayed(1,300);
                    isFrist = false;
                }

            }
        });
    }



    public void expand() {
        expandableSelectorAnimator.expand(animType);
        notifyExpand();
        updateBackground();
    }

    public void setOnExpandableItemClickListener(OnExpandableItemClickListener clickListener) {
        this.clickListener = clickListener;
    }


    private void initializeView(AttributeSet attrs) {
        TypedArray attributes =
                getContext().obtainStyledAttributes(attrs, R.styleable.expandable_selector);
        initializeAnimationDuration(attributes);
        initializeHideBackgroundIfCollapsed(attributes);
        attributes.recycle();
    }

    private void initializeHideBackgroundIfCollapsed(TypedArray attributes) {
        hideBackgroundIfCollapsed =
                attributes.getBoolean(R.styleable.expandable_selector_hide_background_if_collapsed, false);
        expandedBackground = getBackground();
        updateBackground();
    }

    private void initializeAnimationDuration(TypedArray attributes) {
        int animationDuration =
                attributes.getInteger(R.styleable.expandable_selector_animation_duration,
                        DEFAULT_ANIMATION_DURATION);
        int expandInterpolatorId =
                attributes.getResourceId(R.styleable.expandable_selector_expand_interpolator,
                        android.R.anim.accelerate_interpolator);
        int containerInterpolatorId =
                attributes.getResourceId(R.styleable.expandable_selector_container_interpolator,
                        android.R.anim.decelerate_interpolator);
        expandableSelectorAnimator = new ExpandableSelectorAnimator(this, animationDuration, expandInterpolatorId,
                 containerInterpolatorId);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private void updateBackground() {
        if (!hideBackgroundIfCollapsed) {
            return;
        }
        setBackgroundDrawable(expandedBackground);
    }

    private void reset() {
        this.expandableItems = Collections.EMPTY_LIST;
        for (View button : buttons) {
            removeView(button);
        }
        this.buttons = new ArrayList<View>();
        expandableSelectorAnimator.reset();
    }

    private void renderExpandableItems() {
        int numberOfItems = expandableItems.size();
        for (int i = 0; i < numberOfItems; i++) {
            ImageView button = (ImageView) initializeButton(i);
            addView(button);
            buttons.add(button);
            expandableSelectorAnimator.initializeButton(button);
            configureButtonContent(button, expandableItems.get((i)));
        }
        expandableSelectorAnimator.setButtons(buttons);
    }

    private void hookListeners() {
        final int numberOfButtons = buttons.size();
        boolean thereIsMoreThanOneButton = numberOfButtons > 1;
        if (thereIsMoreThanOneButton) {
            buttons.get(numberOfButtons - 1).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    notifyButtonClicked(0, v);
                }
            });
        }
        for (int i = 0; i < numberOfButtons - 1; i++) {
            final int buttonPosition = i;
            buttons.get(i).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int buttonIndex = numberOfButtons - 1 - buttonPosition;
                    notifyButtonClicked(buttonIndex, v);
                }
            });
        }
    }

    private void notifyButtonClicked(int itemPosition, View button) {
        if (clickListener != null) {
            clickListener.onExpandableItemClickListener(itemPosition, button);
        }
    }

    private View initializeButton(int expandableItemPosition) {
        ImageView button = null;
        Context context = getContext();
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        button = (ImageView) layoutInflater.inflate(R.layout.expandable_item_image_button, this, false);
        FrameLayout.LayoutParams params=(FrameLayout.LayoutParams)
                    button.getLayoutParams();
        Resources resources = this.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        int width = dm.widthPixels;
        params.width=(width-(expandableItems.size()+2)*CommonUtil.dip2px(context,5)) /expandableItems.size();
        params.height=CommonUtil.dip2px(context,80);
        if(expandableItemPosition == buttons.size() - 1){
            params.setMargins(CommonUtil.dip2px(context,5),0,CommonUtil.dip2px(context,5),0);
        }else{
            params.setMargins(CommonUtil.dip2px(context,5),0,0,0);
        }
        button.setLayoutParams(params);
        button.setScaleType(ImageView.ScaleType.FIT_CENTER);
//        int visibility = expandableItemPosition == 0 ? View.VISIBLE : View.INVISIBLE;
//        button.setVisibility(visibility);
        return button;
    }

    private void configureButtonContent(ImageView button, ExpandableItem expandableItem) {
        ImageView imageButton = button;
        int resourceId = expandableItem.getResourceId();
        imageButton.setImageResource(resourceId);
    }

    private void notifyExpand() {
        if (hasListenerConfigured()) {
            listener.onExpand();
        }
    }

    private boolean hasListenerConfigured() {
        return listener != null;
    }

    private void validateExpandableItem(ExpandableItem expandableItem) {
        if (expandableItem == null) {
            throw new IllegalArgumentException(
                    "You can't use a null instance of ExpandableItem as parameter.");
        }
    }

    private void validateExpandableItems(List<ExpandableItem> expandableItems) {
        if (expandableItems == null) {
            throw new IllegalArgumentException(
                    "The List<ExpandableItem> passed as argument can't be null");
        }
    }

    private void setExpandableItems(List<ExpandableItem> expandableItems) {
        this.expandableItems = new ArrayList<ExpandableItem>(expandableItems);
    }

    private void bringChildsToFront(List<ExpandableItem> expandableItems) {
        int childCount = getChildCount();
        int numberOfExpandableItems = expandableItems.size();
        if (childCount > numberOfExpandableItems) {
            for (int i = 0; i < childCount - numberOfExpandableItems; i++) {
                getChildAt(i).bringToFront();
            }
        }
    }

    public void animOrientation(int animType) {
        this.animType = animType;
    }
}
